/**
 * 选择图片，文件上传的兼容 pc/uniapp的hook文件
 * 包含上传进度/多图上传/单图上传/仅选择文件-后续上传功能/编辑回显等功能
 */

import { computed, ref } from "vue";
import { uploadsUni, uploads  } from "@/api/upload";
type SourceType = "camera" | "album";

interface FileOptionFace {
  accept?: string; // 文件类型
  multiple?: boolean; // 是否多选
  sourceType?: SourceType[];
  autoUpload?: boolean; // 是否选择
  concurrency?: number; // 是否限制并发上传
}
type FileFace = string | File;
interface filesData {
  file?: FileFace;
  viewUrl?: string; //
  progress: number; // 上传进度
  status: number; // 0等待上传 1 上传中  2上传成功 3 上传失败
  data?: any; // 上传后后端返回的值
}

interface UploadFace extends Record<string,any> {
  file: File | string; // 上传文件 h5 file文件 小程序为string，其他可能后端有额外的参数需求
}
type Platform = "h5" | "uniapp"; // 当前平台，小程序 将采用uniapp 上传方法

/**
 *
 * @param platform 平台 可选 h5 | 'uniapp' 默认uniapp
 * @returns
 */
export function useFile(plat: Platform = "uniapp") {
  const files = ref<File[]|string[]>([]); // 文件列表
  const filesData = ref<filesData[]>([]); // 文件带上传进度的列表
  /**
   * file 转可预览的路径
   * @param file
   * @returns
   */
  const getImageUrl = (file: FileFace): string => {
    if (typeof file === "string") {
      return file;
    } else {
      try {
        let _URL = window.URL || window.webkitURL;
        return _URL.createObjectURL(file);
      } catch {
        return "";
      }
    }
  };

  /**
   * 开始上传
   */
  const batchUpload = async () => {
    return new Promise((resolve, reject) => {
      let arr = [];
      let length = filesData.value.length; // 全部调用完成则返回
      for (let i = 0; i < filesData.value.length; i++) {
        const item = filesData.value[i];
        const index = i;
        if ((item.status == 0 || item.status == 3) && item.file) {
          filesData.value[index].status = 1;

          
          Uploads({ file: item.file! }, (e: any) => progressFunction(e, index))
            .then((data) => {
              filesData.value[index].status = 2;
              filesData.value[index].data = data;
            })
            .catch((err) => {
              filesData.value[index].status = 3;
            })
            .finally(() => {
              length--;
              console.log(length);
              if (length === 0) {
                resolve(filesData.value);
              }
            });
        } else {
          length--;
          if (length === 0) {
            resolve(filesData.value);
          }
        }
      }
    });
  };
  /**
   * 如果是单选，便于选择第一个，不用复杂判断
   */
  const fileValue = computed(() => {
    return files.value && files.value.length > 0 ? files.value[0] : undefined;
  });
  /**
   * 可预览的选择文件列表
   */
  const fileList = computed(() => {
    if (!files.value) return [];
    return files.value.map((v) => {
      return getImageUrl(v);
    });
  });
  /**
   * 初始化列表，常常用于修改传入默认 数据
   * @param data
   */
  const initVal = (data: string | string[]) => {
    if (typeof data === "string") {
      data = data.split(",");
    }
    files.value = [];
    filesData.value = [];
    data.forEach((v) => {
      files.value.push(v);
      filesData.value.push({
        file: undefined,
        progress: 100,
        status: 2,
        viewUrl: v,
      });
    });
  };

  /**
   * 文件上传
   * @param data
   * @param uploadProgress  进度返回
   * @returns
   */
  const Uploads = (
    data: UploadFace,
    uploadProgress?: Function
  ): Promise => {
    return new Promise((resolve, reject) => {
      if (platform == "h5") {
        uploads(data, uploadProgress)
          .then((res) => {
            let { data } = res;
            resolve(data);
          })
          .catch((err) => {
            console.log("失败");
          }).finally;
      } else {
        uploadsUni(data, uploadProgress)
          .then((res) => {
            uni.hideLoading();
            let { data } = res;
            resolve(data);
          })
          .catch((err) => {
            console.log(err);
            uni.hideLoading();
            console.log("失败");
          }).finally;
      }
    });
  };
  const progressFunction = (e: any, index: number) => {
    console.log(e);
    filesData.value[index].progress = e.progress;
  };
  /**
   * 添加文件
   * @param file  文件
   * @param options
   */
  const addFile = async (
    file: FileFace[],
    options: FileOptionFace = {
      multiple: false,
      autoUpload: false,
    }
  ) => {
    const { multiple, autoUpload, concurrency } = options;

    for (let i = 0; i < file.length; i++) {
      console.log(length);
      if (multiple) {
        files.value.push(file[i]);
      } else {
        files.value= [file[i]];
      }
      let index = files.value.length - 1;
      filesData.value[index] = {
        file: file[i],
        progress: 0,
        status: 0,
        viewUrl: getImageUrl(file[i]),
      };
      console.log(filesData.value);
      if (autoUpload) {
        console.log('开始上传');
        
        console.log(file);
        
        await Uploads({ file: file[i] }, (e: any) => progressFunction(e, index))
          .then((res) => {
            filesData.value[index].data = res;
            filesData.value[index].status = 2;
          })
          .catch((err) => {
            filesData.value[index].status = 3;
          });
      }
    }
  };

  /**
   * 选择文件
   * @param data
   * @param options   autoUpload:是否直接选择后上传 concurrency(并发上传暂未实现) accept 选择文件类型（h5）   multiple（批量选择）
   * @returns 文件列表
   * 完整使用方法
   * handleChooseImage(
   * {accept:'image/*',multiple:true,autoUpload:true,concurrency:0}
   * )
   */
  const handleChooseImage = (
    option: FileOptionFace = {
      sourceType: [],
    }
  ): Promise<File[]> => {
    const { sourceType } = option;

    return new Promise(async (resolve, reject) => {
      if (ish5) {
        createInput(option).then(async (file) => {
          await addFile(file, option);
          resolve(files.value);
        });
      } else {
        // #ifdef H5
        // h5 采用传统上传
        createInput(option).then(async (file) => {
          console.log(file);
          await addFile(file, option);
          resolve(files.value);
        });
        // #endif
        // #ifndef H5
        uni.chooseImage({
          sourceType,
          success: async (chooseImageRes) => {
            let fi = chooseImageRes.tempFilePaths;
            if (typeof fi === "string") {
              fi = [fi];
            }
            await addFile(fi, option);
            resolve(files.value);
          },
        });
        // #endif
      }
    });
  };
  /**
   * 创建Input 选择文件
   * @param options
   * @returns
   */
  const createInput = (options: FileInputFace = {}): Promise => {
    const { accept, multiple } = options;
    console.log("创建Input");
    return new Promise((resolve, reject) => {
      var input: HTMLInputElement = document.createElement("input"); // 创建一个 a 标签
      input.accept = accept || "*";
      input.type = "file";
      input.multiple = multiple ? true : false;
      input.onchange = (e: any) => {
        resolve(e.target.files);
      };
      document.body.appendChild(input);
      input.click();
      function monitor() {
        document.removeEventListener("mousemove", monitor);
        document.body.removeChild(input);
      }
      document.addEventListener("mousemove", monitor, false);
    });
  };

  return {
    createInput,
    handleChooseImage,
    filesData,
    files,
    fileList,
    fileValue,
    initVal,
    batchUpload,
  };
}